package kibahed.server.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import kibahed.interfaces.cards.ESuite;
import kibahed.server.connection.ClientThread;
import kibahed.server.connection.Server;

public class ServerStartPanel extends JPanel {

	private Server server = null;
	ClientThread echo;
	JMenuBar menu = new JMenuBar();
	JFrame frame = new JFrame();
	JPanel topPanel = new JPanel();
	JPanel midPanel = new JPanel();
	JPanel botPanel = new JPanel();
	JPanel clientPanel = new JPanel();

	JLabel ipLabel = new JLabel("");
	JLabel ipDescription = new JLabel("Server ip:");
	JLabel statusLabel = new JLabel("Status");
	JLabel status = new JLabel();

	JLabel portLabel = new JLabel("Port");
	JTextField portField = new JTextField(10);
	JButton startButton = new JButton("Start Server");
	JButton stopButton = new JButton("Stop Server");
	JButton refreshButton = new JButton("Refresh");
	Thread statusThread;
	int clientUpdateCounter = 0;
	boolean isStatusThreadRunning = true;

	public static void main(String[] args) {

		ServerStartPanel ssp = new ServerStartPanel();
	}

	public ServerStartPanel() {
		init();
		frame.add(this);
		frame.pack();
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	private void init() {
		this.server = new Server();

		this.setLayout(new BorderLayout());

		topPanel.setLayout(new FlowLayout());
		topPanel.add(ipDescription);
		topPanel.add(ipLabel);
		ipLabel.setText(IpErmittler.getIpAdresse());
		topPanel.add(statusLabel);
		topPanel.add(status);
		fillClientPanel();

		this.add(topPanel, BorderLayout.NORTH);

		this.add(midPanel, BorderLayout.CENTER);
		this.add(botPanel, BorderLayout.SOUTH);
		clientPanel.setPreferredSize(new Dimension(400, 100));
		JScrollPane clientScrollPane = new JScrollPane();
		clientScrollPane.setViewportView(clientPanel);
		this.add(clientScrollPane, BorderLayout.EAST);
		frame.getRootPane().setDefaultButton(startButton);
		portField.setText(String.format("%s", server.getPort()));
		portField.setSelectionStart(0);
		portField.setSelectionEnd(portField.getText().length());
		midPanel.setLayout(new GridLayout(0, 4));

		midPanel.add(portLabel);
		midPanel.add(portField);
		statusThread = new Thread() {

			@Override
			public void run() {
				while (isStatusThreadRunning) {
					status.setText(server.getStatus());
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				;
			}

		};
		statusThread.start();

		botPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
		botPanel.add(startButton);
		startButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				int port = server.getPort();
				try {
					port = Integer.parseInt(portField.getText());
					server.setPort(port);
					frame.getRootPane().setDefaultButton(stopButton);
				} catch (Exception ex) {
					ex.printStackTrace();
				}

				server.startServer();

				System.out.println("Server started");
			}
		});
		botPanel.add(stopButton);
		stopButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				server.stopServer();
				System.out.println("Server stopped");
				frame.getRootPane().setDefaultButton(startButton);
			}
		});

		botPanel.add(refreshButton);
		refreshButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.out.println("Refreshing Client list");
				fillClientPanel();

			}
		});

	}

	private void fillClientPanel() {
		clientUpdateCounter++;
		clientPanel.removeAll();
		clientPanel.setLayout(new GridLayout(0, 1));
		final Set<ClientThread> clientThreads = new HashSet<ClientThread>();
		synchronized (server.getClients()) {
			for (Object o : server.getClients()) {
				if (o instanceof ClientThread) {
					final ClientThread th = (ClientThread) o;
					clientThreads.add(th);
					System.out.println(String.format("Found ClientThread %s",
							th.toString()));
					final JLabel clientName = new JLabel(String.format("%s:%s",
							th.getIpAdress(), th.getPort()));
					final JTextField inputField = new JTextField(10);
					final JButton sendButton = new JButton("send");
					sendButton.addActionListener(new ActionListener() {

						@Override
						public void actionPerformed(ActionEvent arg0) {
							th.sendMessage(inputField.getText());

						}
					});
					final JPanel helpPanel = new JPanel();
					helpPanel.setPreferredSize(new Dimension(100, 200));
					helpPanel.setLayout(new GridLayout(0, 1));
					final JScrollPane scrollPane = new JScrollPane();
					final JTextArea messageArea = new JTextArea();
					messageArea.setAutoscrolls(true);
					scrollPane.setViewportView(messageArea);
					final JPanel helpPanel2 = new JPanel();
					helpPanel2.setLayout(new FlowLayout());
					helpPanel2.add(clientName);
					helpPanel2.add(inputField);
					helpPanel2.add(sendButton);
					Thread messageUpdate = new Thread() {

						@Override
						public void run() {
							final int counter = clientUpdateCounter;
							while (clientUpdateCounter == counter) {
								if (!messageArea.hasFocus()
										&& !scrollPane.hasFocus()) {
									messageArea.setText(th.getMessages());
									messageArea.setCaretPosition(messageArea
											.getText().length());
									if (scrollPane.getVerticalScrollBar() != null) {
										scrollPane
												.getVerticalScrollBar()
												.setValue(
														scrollPane
																.getVerticalScrollBar()
																.getMaximum());
									}
									scrollPane.validate();
									messageArea.validate();
									if (!th.isAlive()
											&& clientUpdateCounter == counter) {
										fillClientPanel();
									}
								}
								try {
									Thread.sleep(100);
								} catch (InterruptedException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
							System.out
									.println("Terminated message update Thread");
						}

					};
					messageUpdate.start();
					helpPanel.add(scrollPane);
					helpPanel.add(helpPanel2);
					clientPanel.add(helpPanel);
					clientPanel.validate();
				}
			}
		}

		Thread clientWatcher = new Thread() {

			@Override
			public void run() {
				final int counter = clientUpdateCounter;
				marker: while (clientUpdateCounter == counter) {
					for (Object o : server.getClients()) {
						if (o instanceof ClientThread) {
							final ClientThread th = (ClientThread) o;
							if (!clientThreads.contains(th)) {
								System.out.println("Breaking ClientUpdater");
								fillClientPanel();
								break marker;
							}
						}
					}
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}

		};
		clientWatcher.start();
	}

}
